/*****************************************************************
**                                                              **
**  Copyright (C) 2004 Amlogic,Inc.                             **
**  All rights reserved                                         **
**        Filename : aw_avi_app.c /Project:AVOS                ** 
**        Revision : 1.0                                        **
**                                                              **
*****************************************************************/
#ifdef ENABLE_NETWORK  

#include "../menu.h"
#include "includes.h"
#include "aw_windows.h"
#include "app.h"
#include "user.h"
#include "menu.h"
#include "aw_init_display.h"
#include "aw_sys_app.h"
#include "aw_gui_app.h"
#include "filenav.h"
//#include "../filestatus/filestatus.h"
#include <Drivers/usb/gadget/dsc.h>
//#include "WinHandleDef.h"
#include "aw_network.h"
#include <filesystem/extend/fileio.h>
#include "net_app.h"
#include "netdiskdev.h"
#include "filesystem/netfs/netfs.h"
//#include "../Osd_table.h"
//#include "winselectevent.h"
//#include "Winmultiupevent.h"
//#include "CardMultiUpEvent.h"
//#include "WinHomeEvent.h"
//#include "Menu_ID_Define.h"
//#include "aw_config.h"

#include "net/amupnp/device.h"

#ifdef WPA_SUPPORT
#include "wpa_supplicant/config_ssid.h"
#include "wpa_supplicant/wpa_app.h"
#endif /* WPA_SUPPORT */

extern INT8U GetCurSearchMode(void);
extern void ProcessScroll(INT16U Process,INT8U use_dcache);
extern void SelectListSetNameDisp(char *listname, char *filename);
extern int avos_tzset(char *offset, int dst);
//extern int SetKodakWifiConfig(struct kodak_iw_config *config);
extern void GetSNStringFromSNVaule(char *string,int vaule);

struct iwscan_state iwscanState;
struct iwscan_state *Scan_Result = NULL;

static struct iwconfig_state iwconfigState;
INT8U ssid_num = 0;

void Dynamic_IP(void)
{
    struct netif_config ifconfig;
    int ret;

    memset(&ifconfig, 0, sizeof(ifconfig));

    ifconfig.has_ipaddr = 1;
    ifconfig.dhcp = 1;

    ret = netif_set_config(&ifconfig);

#ifdef DEBUG_NETWORK_SETTING	
    if (ret)
		printf("Network interface configuration error %d\n", ret);
#endif
}

void Setup_Static_IP(char *ipaddr, 
                     char *maskaddr, 
                     char *gatewayaddr, 
                     char *pridnsaddr,
                     char *secondary_dns)
{
	int ret;
	struct netif_config ifconfig;

	memset(&ifconfig, 0, sizeof(ifconfig));

	ifconfig.has_ipaddr = 1;

	if (!inet_aton(ipaddr, &ifconfig.ipaddr)) 
	{
#ifdef DEBUG_NETWORK_SETTING	
        printf("Invalid IP address %s\n", ipaddr);
#endif
	}

	if (!inet_aton(maskaddr, &ifconfig.netmask)) 
	{
#ifdef DEBUG_NETWORK_SETTING	
        printf("Invalid netmask address %s\n", maskaddr);
#endif
	}

	if (!inet_aton(gatewayaddr, &ifconfig.gateway)) 
	{
#ifdef DEBUG_NETWORK_SETTING	
        printf("Invalid gateway address %s\n", gatewayaddr);
#endif
	}

	if (!inet_aton(pridnsaddr, &ifconfig.primary_dns)) 
	{
#ifdef DEBUG_NETWORK_SETTING	
        printf("Invalid primary DNS address %s\n", pridnsaddr);
#endif
	}

	if (secondary_dns &&
        !inet_aton(secondary_dns, &ifconfig.secondary_dns))
	{
#ifdef DEBUG_NETWORK_SETTING	
        printf("Invalid secondary DNS address %s\n", secondary_dns);
#endif
	}

	ret = netif_set_config(&ifconfig);

	if (ret) 
	{
#ifdef DEBUG_NETWORK_SETTING		      
		printf("Network interface configuration error %d\n", ret);
#endif
    }
}





void UI_Display_Scanresult(struct iwscan_state *state)
{
    PHWND dir_hwnd=NULL;
    struct wireless_scan *curr = NULL;
    int index = 0;
    
    unsigned short net_qual_str[20];
    unsigned short temp;
    short j,i;
    char t[IW_ESSID_MAX_SIZE + 1];
    INT8U net_intension;
    char net_percent[8] = "";
    int percent = 0;

    if (state && !state->errno) 
    {
        percent = state->progress * 100 / state->delay;

        if (state->progress < state->delay) 
         {
            /*scanning,display scan percent*/
           // ProcessScroll(percent,1);
            return;
        }
        else
            /*scan complete*/
            curr = state->scan;
    }

    if (curr) 
    {
        /* net_id_str[][] is a 20 x (IW_ESSID_MAX_SIZE + 1) 2D array. */
        while (curr && ssid_num < 20)
        {
            /* Display non-hidden, infrastructure access point only. */
            if ( curr->b.has_essid &&
                 curr->b.essid_on  &&
                 curr->b.essid[0]  &&
                 curr->b.has_mode  &&
                 curr->b.mode == IW_MODE_MASTER)
            {
                /*show scan result*/
		#if 0
			
                strncpy(net_id_str[ssid_num],curr->b.essid, IW_ESSID_MAX_SIZE);

                strncpy(net_id_intension_str[ssid_num],curr->b.essid, IW_ESSID_MAX_SIZE);
                if (strlen(curr->b.essid) > DISP_AP_NAME_BAR_LENGTH)
                {
                    net_id_intension_str[ssid_num][DISP_AP_NAME_BAR_LENGTH]='.';
                    net_id_intension_str[ssid_num][DISP_AP_NAME_BAR_LENGTH+1]='.';
                    net_id_intension_str[ssid_num][DISP_AP_NAME_BAR_LENGTH+2]='.';
                    net_id_intension_str[ssid_num][DISP_AP_NAME_BAR_LENGTH+3]=0;
                }
                net_qual_str[ssid_num] = curr->stats.qual.level;
                net_intension = net_qual_str[ssid_num];
                if(net_intension==0)
                	net_intension=1;

                snprintf(net_percent, 8, " (%d%%)", net_intension);
                strcat(net_id_intension_str[ssid_num], net_percent);
	
                
                // Debug code to display security setting of AP.
                switch (curr->has_security) {
                case IW_SECURITY_WEP:
                    strcat(net_id_intension_str[ssid_num], " (WEP)");
                    break;
                case IW_SECURITY_WPA:
                    strcat(net_id_intension_str[ssid_num], " (WPA)");
                    break;
                case IW_SECURITY_WPA2:
                    strcat(net_id_intension_str[ssid_num], " (WPA2)");
                    break;
                case IW_SECURITY_NONE:
                default:
                    strcat(net_id_intension_str[ssid_num], " (NONE)");
                    // Show nothing if no security or any other value.
                    break;
                }
             #endif
		    ssid_num++;
		
            }

          	curr = curr->next;
        }
#if 1
        for(j=0;j<=ssid_num-2;j++)
        	for(i=0;i<ssid_num-1-j;i++)
        		if(net_qual_str[i]<net_qual_str[i+1])
        		{
        		
                    temp = net_qual_str[i];
                    net_qual_str[i] = net_qual_str[i+1];
                    net_qual_str[i+1] = temp;
			#if 0
                    strncpy(t,net_id_str[i],IW_ESSID_MAX_SIZE);
                    strncpy(net_id_str[i],net_id_str[i+1],IW_ESSID_MAX_SIZE);
                    strncpy(net_id_str[i+1],t,IW_ESSID_MAX_SIZE);	
                    strncpy(t,net_id_intension_str[i],IW_ESSID_MAX_SIZE);
                    strncpy(net_id_intension_str[i],net_id_intension_str[i+1],IW_ESSID_MAX_SIZE);
                    strncpy(net_id_intension_str[i+1],t,IW_ESSID_MAX_SIZE); 
			#endif
			
        		}
#endif
#if 0
        if(ssid_num!=0)
        {
        	//PresetMenuTotalSelect(ssid_num+1,ID_MENU_NET_SSID_LIST);	 
        	       // TotalSelectNumber=ssid_num+1;
                        GUIHideWindow("WinSetupMenu");
			GUIShowWindow("Network_Setup");
			
		         dir_hwnd = AWFindWinCtrlByName("ManuScan") ;
                         if(AWIsVisibleWinControl(dir_hwnd))
                          {
                          AWHideWinControl(dir_hwnd);   
                          }
                         dir_hwnd = AWFindWinCtrlByName("Scan_result") ;
                         if(!AWIsVisibleWinControl(dir_hwnd))
                          {
                           AWShowWinControl(dir_hwnd,0);   
                           AWSetFocus(dir_hwnd) ;			
                          }
			
      	}
      	else
      	{
      	 // PresetMenuConnect(ID_MENU_NO_WIRELESS_NETWORK);
          GUIShowWindow("Windialog");
      	}
#endif
    }
    else 
    {
        //PresetMenuConnect(ID_MENU_NO_WIRELESS_NETWORK);
        //GUIShowWindow("Windialog");
        //printf("Scan failed: errno %d\n", state->errno);
    }

    /* Routine is responsible for freeing the memory after completion. */
    //iw_free_scan_list(state);
}


int Start_Scan(void)
{
    INT16U pCmds;
    INT32U pCmdsParam;
    INT8U  pCmdSrc;
    INT8U  pCmdTimeout = 0;

    if (Scan_Result) {
        iw_free_scan_list(Scan_Result);
        Scan_Result = NULL;
    }
	ssid_num = 0;	
    /* Scan timeout 4 seconds, report progress every 500ms. */
    memset(&iwscanState, 0, sizeof(iwscanState));
    iwscanState.delay = 4 * 1000;
    iwscanState.interval = 500;

    AWGetAppID(MEDIA_NET, &pCmdSrc);
    pCmds      = CM_NET_SET_WIFI_SCANSTART;
    pCmdsParam = (INT32U) &iwscanState;
    AWAddCmdSet(1, &pCmds, &pCmdsParam, &pCmdTimeout, pCmdSrc, NULL);
    return 0;
}



void Start_Connect(struct aml_iw_config *config)
{
    INT16U pCmds;
    INT32U pCmdsParam;
    INT8U  pCmdSrc;
    INT8U  pCmdTimeout = 0;
    INT8U  useDhcp = 0;
    wireless_config info;

    /**
     *  Default to use DHCP when user switch between access point.
     */
    if (!iw_get_basic_config("zd1211b", &info)) {
        if (strcmp(info.essid, config->essid))
            Dynamic_IP();
    }

    /* Reset all fields. */
    memset(&iwconfigState, 0, sizeof(iwconfigState));

    /* Set ESSID related field. */
    iwconfigState.has_essid = 1;
    iwconfigState.essid_on  = 1;

    strncpy(iwconfigState.essid, config->essid, IW_ESSID_MAX_SIZE);

    /* Mode is always infrastructure. */
    config->mode = IW_MODE_INFRA;

    /* Set mode field. */
    iwconfigState.has_mode = 1;
    iwconfigState.mode = config->mode; /* Set mode. */

    /* Set encryption. */
    iwconfigState.has_key = config->security;
    iwconfigState.key_size = config->key_len;
    memcpy(iwconfigState.key, config->key, config->key_len);

    /* Timeout after 30 seconds, and notify progress every 500 ms. */
    iwconfigState.timeout = 30 * 1000;
    iwconfigState.interval = 500;

    AWGetAppID(MEDIA_NET, &pCmdSrc);
    pCmds      = CM_NET_SET_WIFI_CONFIG;
    pCmdsParam = (INT32U) &iwconfigState;

    AWAddCmdSet(1, &pCmds, &pCmdsParam, &pCmdTimeout, pCmdSrc, NULL);

    /**
     *  Need to save WiFi configuration in application for now because
     *  of WPA. WPA is configured through WPA supplicant, while other
     *  WiFi configuration currently goes through IOCTL directly.
     *
     *  In the future, probably should make all WiFi setting through
     *  WPA supplicant.
     */
    {
    #if 0
       int ret =  SetWifiConfig(config);
	   if(ret ==FALSE){
	   	AVOS_printf("Not write in\n");
		ret = 0;
	   	}
   #endif
    }
}

void Enable_Time_Sync(void)
{
    INT16U pCmds;
    INT32U pCmdsParam;
    INT8U  pCmdSrc;
    INT8U  pCmdTimeout = 0;

    AWGetAppID(MEDIA_NET, &pCmdSrc);
    pCmds      = CM_NET_SET_SNTP_ENABLE;
    pCmdsParam = 60 * 60; // Request SNTP sync every hour (3600 seconds)
    AWAddCmdSet(1, &pCmds, &pCmdsParam, &pCmdTimeout, pCmdSrc, NULL);
}



void Disable_Time_Sync(void)
{
    INT16U pCmds;
    INT32U pCmdsParam;
    INT8U  pCmdSrc;
    INT8U  pCmdTimeout = 0;
 
    AWGetAppID(MEDIA_NET, &pCmdSrc);
    pCmds      = CM_NET_SET_SNTP_DISABLE;
    pCmdsParam = 0;
    AWAddCmdSet(1, &pCmds, &pCmdsParam, &pCmdTimeout, pCmdSrc, NULL);
}


void Set_WiFi_Status(int status)
{
    struct netif_config ifconfig;
    int ret;

    memset(&ifconfig, 0, sizeof(ifconfig));

    /* Bring up/down network interface. */
    ifconfig.has_status = 1;
    ifconfig.status = (status ? 1 : 0);

    ret = netif_set_config(&ifconfig);
#ifdef DEBUG_NETWORK_SETTING	
    if (ret)
		printf("Network interface configuration error %d\n", ret);
#endif
}

void Set_Time_Zone(short i)
{ 
    char *tz_offset[] = {
        "+12:00",
        "+11:00",
        "+10:00", 
        "+9:00",  
        "+8:00",
        "+7:00",
        "+07:00",
        "+07:00",
        "+06:00",
        "+06:00",   
        "+06:00",
        "+06:00", 
        "+05:00",
        "+05:00", 
        "+05:00", 
        "+04:00", 
        "+04:00",
        "+04:00", 
        "+03:30",
        "+03:00", 
        "+03:00", 
        "+03:00", 
        "+02:00",
        "+01:00", 
        "+01:00",
        "00:00",
        "00:00",
        "-01:00",
        "-01:00",
        "-01:00",
        "-01:00",
        "-01:00",
        "-02:00",
        "-02:00",
        "-02:00",
        "-02:00",
        "-02:00",
        "-02:00",
        "-03:00",
        "-03:00",
        "-03:00",
        "-03:00",
        "-03:30",
        "-04:00",
        "-04:00",
        "-04:30",
        "-05:00",
        "-05:00",
        "-05:30",
        "-05:45",
        "-06:00",
        "-06:00",
        "-06:00",
        "-06:30",
        "-07:00",
        "-07:00",
        "-08:00",
        "-08:00",
        "-08:00",
        "-08:00",
        "-08:00",
        "-09:00",
        "-09:00",
        "-09:00",
        "-09:30",
        "-09:30",
        "-10:00",
        "-10:00",
        "-10:00",
        "-10:00",
        "-10:00",
        "-11:00",
        "-12:00",
        "-12:00",
        "-13:00"
    };

    int tz_dst[] = {
        0,
        0,
        0,
        1,
        1,
        1,
        1,
        0,
        0,
        0,
        1,
        1,
        1,
        0,
        0,
        1,
        1,
        0,
        1,
        1,
        1,
        0,
        1,
        1,
        0,
        1,
        0,
        1,
        1,
        1,
        0,
        1,
        1,
        1,
        1,
        1,
        0,
        0,
        0,
        1,
        0,
        1,
        1,
        0,
        1,
        0,
        1,
        0,
        0,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        0,
        0,
        0,
        1,
        0,
        1,
        1,
        0,
        1,
        1,
        0,
        0, 
        0,
        1,
        0            
    };

    if (avos_tzset(tz_offset[i], tz_dst[i]))
    {
#ifdef DEBUG_NETWORK_SETTING
    	printf("Failed to set timezone.\n");
#endif
    }
}

int Get_Security_Setting(struct iwscan_state *state, char *ssid)
{
    struct wireless_scan *curr;

    if (state && state->scan)
    {
        curr = state->scan;
        while (curr)
        {
            if (strcmp((curr->b.essid),ssid) == 0)
                return curr->has_security;
            else
                curr = curr->next;
        }
    }

    return IW_SECURITY_NONE;
}
//MultiUpFileListItem folderlist_item[MAX_LIST_NUM];

char UPnPdevice_Name[MAX_UPNPDEVICE_NUM][MAX_DEVICE_NAME_LENGTH]; 
#if 0
int Get_UPnPServer_List(void)
{
	char*temp;
	int i = 0;
	INT32S ret = -1;
	int start_pos = 0;
	INT8U get_num = MAX_LIST_NUM;	
	MultiUpFileListItem folderlist_item[MAX_LIST_NUM];
	
	memset(folderlist_item,0,sizeof(folderlist_item));	
  	SetFolderSelectList(MAX_LIST_NUM,folderlist_item);
  	ret = FileNavCD("/mnt/"); 
 	if(ret == 0)
  	{
	    temp = FileNavGetCurrDir();
	    memset(gCurDirName,0,MAX_DIR_PATH_LENGTH);
	    strcat(gCurDirName,temp);
  	}  
	GetSelectFolderListCB(start_pos, &get_num, folderlist_item,NAV_IS_DIR, 1);		
	memset(UPnPdevice_Name,0,sizeof(UPnPdevice_Name));
	for(i = 0;i < get_num;i++)
	{
		SelectListSetNameDisp(UPnPdevice_Name[i],(char *)folderlist_item[i].file_name);
	}
	return get_num;
}

AVTimer_t UPnP_Scan_Timer = 0;

int UPnP_Scan_percent = 0;


void UPnP_Scan_Timer_post(void)
{
	int UPnP_Num = 0;
	//if(!UPnP_Scan_Timer)
	//	UPnP_Scan_percent = 
	if(!UPnP_Scan_Timer)
		return;
	if(UPnP_Scan_percent == 100)
	{
		UPnP_Scan_percent = 0;	
		if(UPnP_Scan_Timer){
			AVTimerDelete(UPnP_Scan_Timer);	
			UPnP_Scan_Timer = 0;
		}
		UPnP_Num = Get_UPnPServer_List();
	  	PresetMenuTotalSelect(UPnP_Num+1,ID_MENU_UPNP_DEVICE_LIST);
	  	GUIShowWindow("WinSelect");
	}	
	else
	{
		UPnP_Scan_percent += 10;
		ProcessScroll(UPnP_Scan_percent,1);	
	}	
}

void UPnP_Scan_Timer_Func(void)
{
	//if(UPnP_Scan_percent == 100)
	//{
	//	if(UPnP_Scan_Timer){
	//		AVTimerDelete(UPnP_Scan_Timer);	
	//		UPnP_Scan_Timer = 0;
	//	}
	//}
	AWGUISendNMMessage(MEDIA_GUI,NM_BROWSER_TASK_READY,TASK_BROWSER_UPNPSCAN);
#if 0
	int UPnP_Num = 0;
	if(UPnP_Scan_percent == 100)
	{
		AVTimerDelete(UPnP_Scan_Timer);	
		UPnP_Scan_Timer = 0;
		UPnP_Scan_percent = 0;
		
		UPnP_Num = Get_UPnPServer_List();
	  	PresetMenuTotalSelect(UPnP_Num+1,ID_MENU_UPNP_DEVICE_LIST);
	  	GUIShowWindow("WinSelect");
	}
	
	else
	{
		UPnP_Scan_percent += 10;
		ProcessScroll(UPnP_Scan_percent,1);	
	}
#endif
}




INT32S Creat_UPnP_Scan_Timer(void)
{
  if (!UPnP_Scan_Timer) 
  {
  	UPnP_Scan_Timer = AVTimerCreateFlag(800, (TIMER_CB_t)UPnP_Scan_Timer_Func , NULL, AVTIMER_FLAG_PERIODIC); 
  }
  else
  {
  	AVTimerEnable(UPnP_Scan_Timer);
  }
  UPnP_Scan_percent = 0;
  return 1;
}
#endif

int WEP_key_Verify(char *ptr,short num,char *Hexadecimal)
{
	//char Hexadecimal[60];
	
	int i,len=0;
	
	int temph,templ;
	
	memset(Hexadecimal,0,sizeof(Hexadecimal));
	
	if(num==5 || num==13)
	{
		strcpy(Hexadecimal,ptr);
		return num;
	}
	
	else if(num==10 ||num==26)
	{
		for(i=0;i<num;i++)
			{
				if((('0'<=*(ptr+i))&&(*(ptr+i)<='9'))||('A'<=*(ptr+i)&&(*(ptr+i)<='F'))||(('a'<=*(ptr+i))&&(*(ptr+i)<='f')))
				{
					if(i%2==0)
					{
						sscanf((ptr+i), "%1X%1X", &temph, &templ);
						templ |= temph << 4;
						//printf("%c\n",(unsigned char) (templ & 0xFF));
						Hexadecimal[len++] = (unsigned char) (templ & 0xFF);
					}
				}
				else
				{
				 return 0;//ilegl character
				}
			}
			Hexadecimal[len] = '\0';
			return len;	
	}	
	else
	{
		return 0;//erro number	
	}
}


int Get_AP_Mode_Setting(struct iwscan_state *state, char *ssid)
{
	  struct wireless_scan *curr;
    int mode = IW_MODE_INFRA;

    if (state && state->scan)
    {
        curr = state->scan;
        while (curr)
        {
            if(strcmp((curr->b.essid),ssid) == 0) 
            {
            	if(state->scan->b.mode == IW_MODE_ADHOC)
            	{
            		mode = IW_MODE_ADHOC;
            	}
            	break;
            }
          	curr = curr->next;
        }
    }
    return mode;
}
#if 0
#include "kodak_upnp_icon.c"

void UPnPRegisterDeviceDescription(void)
{
    static UPnPDeviceDescription_t *desc;
    static char serialNumber[13] = "";
    static char friendlyName[KODAK_FRAME_NAME_LEN + 1] = "";

    if (desc == NULL) {
        memset(serialNumber, 0, 13);
        GetSNStringFromSNVaule(serialNumber, GetSN_NumberPara());

        desc = AVMem_malloc(sizeof(*desc));
        if (desc) {
            desc->manufacturer = PRODUCT_DESC_VENDOR;
            desc->manufacturerURL = "http://www.kodak.com";
            desc->modelDescription = PRODUCT_DESC_MODE;
            desc->modelName = PRODUCT_DESC_MODE;
            desc->modelNumber = MODEL_NUMBER_STRING;
            desc->modelURL = "http://www.kodak.com";
            desc->serialNumber = serialNumber;
            //desc->udn = "";
            desc->numIcon = sizeof(kodak_upnp_icons) / sizeof(UPnPDeviceIcon_t);
            desc->icons = kodak_upnp_icons;
        }
    }

    if (desc) {
        /* Get frame name everytime. */
        desc->friendlyName = (char *)GetFrameNamePara();
        if (desc->friendlyName)
            strncpy(friendlyName, desc->friendlyName, KODAK_FRAME_NAME_LEN);
        else
            strncpy(friendlyName, KODAK_FRAME_NAME_DEFAULT, KODAK_FRAME_NAME_LEN);

        desc->friendlyName = friendlyName;
        upnp_register_device_description(desc);
    }
}
#endif
#endif /* ENABLE_NETWORK */

